home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / rayshade / libshade / fastimage.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  330 lines

  1.  
  2. /* from fastimage.c */
  3.  
  4. #include <stdio.h>
  5. #include <gl/image.h>
  6.  
  7. static struct
  8. {
  9.     FILE        *ifile;
  10.     IMAGE        header;
  11.     FILE        *inf;
  12.     unsigned char    *rledat, *verdat;
  13.     int            rlebuflen;
  14.     long        *starttab, *lengthtab;
  15. }im;
  16.  
  17. SgiRgbOpen(name, type, xsize, ysize, zsize)
  18. char *name;
  19. int type;
  20. int *xsize, *ysize, *zsize;
  21. {
  22.  
  23.     im.header = (IMAGE *)malloc(sizeof(IMAGE));
  24.     im.header->xsize = xsize;
  25.     im.header->ysize = ysize;
  26.     im.header->zsize = zsize;
  27.     im.header->type  = type;
  28.  
  29.     if(ISRLE(type))
  30.     {
  31.         im.tablen    = ysize * zsize * sizeof(long);
  32.         im.starttab  = (long *)malloc(im.tablen);
  33.         im.lengthtab = (long *)malloc(im.tablen);
  34.         im.rlebuflen = 1.05*xsize+10;
  35.         im.rledat    = (unsigned char *)malloc(im.rlebuflen);
  36.     }
  37.  
  38.     im.file = fopen(name,"w");
  39.     if(!im.file)
  40.     {
  41.         fprintf(stderr,"SgiRgbOpen: can't open SGI RGB file %s\n",name);
  42.         exit(1);
  43.     }
  44. }
  45.  
  46. SgiRgbWriteLine()
  47. {
  48. }
  49.  
  50. SgiRgbClose()
  51. {
  52.     int y,z;
  53.  
  54.     fwrite(&im.header,sizeof(IMAGE),1,im.file);
  55.     fwrite(&im.header,sizeof(IMAGE),1,im.file);
  56.     fseek(im.file,512,SEEK_SET);
  57.     fwrite(im.starttab,im.tablen,1,im.file);
  58.     fwrite(im.lengthtab,im.tablen,1,im.file);
  59.  
  60.     for(y = 0; y < im.header->ysize; y++)
  61.     {
  62.         for(z = 0; z < im.header->zsize; z++)
  63.         {
  64.             fseek(im.file, im.starttab[y+z*im.header->ysize], SEEK_SET);
  65.             fwrite(im.rledat, im.lengthtab[y+z*im.header->ysize], 1, im.file);
  66.         }
  67.     }
  68.  
  69.     fclose(im.file);
  70. }
  71.  
  72. /*
  73.  *      longimagedata -
  74.  *              read img a B/W RGB or RGBA iris image file and return a
  75.  *      pointer to an array of longs.
  76.  *
  77.  */
  78. sgiRGBwrite()
  79. char *name;
  80. {
  81.     unsigned long *base, *lptr;
  82.     unsigned char *rledat, *verdat;
  83.     long *starttab, *lengthtab;
  84.     FILE *inf;
  85.     IMAGE *image;
  86.     int y, z, pos, len, tablen;
  87.     int xsize, ysize, zsize;
  88.     int bpp, rle, cur, badorder;
  89.     int rlebuflen;
  90.  
  91.     inf = fopen(name,"r");
  92.     if(!inf) {
  93.         fprintf(stderr,"longimagedata: can't open image file %s\n",name);
  94.         exit(1);
  95.     }
  96.     fread(image,sizeof(IMAGE),1,inf);
  97.     if(image->imagic != IMAGIC) {
  98.         fprintf(stderr,"longimagedata: bad magic number in image file\n");
  99.         exit(1);
  100.     }
  101.     rle = ISRLE(image->type);
  102.     bpp = BPP(image->type);
  103.     if(bpp != 1 ) {
  104.         fprintf(stderr,"longimagedata: image must have 1 byte per pix chan\n");
  105.         exit(1);
  106.     }
  107.     xsize = image->xsize;
  108.     ysize = image->ysize;
  109.     zsize = image->zsize;
  110.     if(rle) {
  111.         tablen = ysize*zsize*sizeof(long);
  112.         starttab = (long *)malloc(tablen);
  113.         lengthtab = (long *)malloc(tablen);
  114.         rlebuflen = 1.05*xsize+10;
  115.         rledat = (unsigned char *)malloc(rlebuflen);
  116.         fseek(inf,512,SEEK_SET);
  117.         fread(starttab,tablen,1,inf);
  118.         fread(lengthtab,tablen,1,inf);
  119.  
  120. /* check data order */
  121.         cur = 0;
  122.         badorder = 0;
  123.         for(y=0; y<ysize; y++) {
  124.             for(z=0; z<zsize; z++) {
  125.                 if(starttab[y+z*ysize]<cur) {
  126.                     badorder = 1;
  127.                     break;
  128.                 }
  129.                 cur = starttab[y+z*ysize];
  130.             }
  131.             if(badorder)
  132.                 break;
  133.         }
  134.         fseek(inf,512+2*tablen,SEEK_SET);
  135.         cur = 512+2*tablen;
  136.         base = (unsigned long *)
  137.                 malloc((xsize*ysize+TAGLEN)*sizeof(long));
  138.         addlongimgtag(base,xsize,ysize);
  139.         if(badorder) {
  140.             for(z=0; z<zsize; z++) {
  141.                 lptr = base;
  142.                 for(y=0; y<ysize; y++) {
  143.                     if(cur != starttab[y+z*ysize]) {
  144.                         fseek(inf,starttab[y+z*ysize],SEEK_SET);
  145.                         cur = starttab[y+z*ysize];
  146.                     }
  147.                     if(lengthtab[y+z*ysize]>rlebuflen) {
  148.                         fprintf(stderr,"longimagedata: rlebuf is too small - bad poop\n");
  149.                         exit(1);
  150.                     }
  151.                     fread(rledat,lengthtab[y+z*ysize],1,inf);
  152.                     cur += lengthtab[y+z*ysize];
  153.                     expandrow(lptr,rledat,3-z);
  154.                     lptr += xsize;
  155.                 }
  156.             }
  157.         } else {
  158.             lptr = base;
  159.             for(y=0; y<ysize; y++) {
  160.                 for(z=0; z<zsize; z++) {
  161.                     if(cur != starttab[y+z*ysize]) {
  162.                         fseek(inf,starttab[y+z*ysize],SEEK_SET);
  163.                         cur = starttab[y+z*ysize];
  164.                     }
  165.                     fread(rledat,lengthtab[y+z*ysize],1,inf);
  166.                     cur += lengthtab[y+z*ysize];
  167.                     expandrow(lptr,rledat,3-z);
  168.                 }
  169.                lptr += xsize;
  170.             }
  171.         }
  172.         if(zsize == 3)
  173.             setalpha(base,xsize*ysize);
  174.         else if(zsize<3)
  175.             copybw(base,xsize*ysize);
  176.         fclose(inf);
  177.         free(starttab);
  178.         free(lengthtab);
  179.         free(rledat);
  180.         free(image);
  181.         return base;
  182.     } else {
  183.         base = (unsigned long *)
  184.                 malloc((xsize*ysize+TAGLEN)*sizeof(long));
  185.         addlongimgtag(base,xsize,ysize);
  186.         verdat = (unsigned char *)malloc(xsize);
  187.         fseek(inf,512,SEEK_SET);
  188.         for(z=0; z<zsize; z++) {
  189.             lptr = base;
  190.             for(y=0; y<ysize; y++) {
  191.                 fread(verdat,xsize,1,inf);
  192.                 interleaverow(lptr,verdat,3-z,xsize);
  193.                 lptr += xsize;
  194.             }
  195.         }
  196.         if(zsize == 3)
  197.             setalpha(base,xsize*ysize);
  198.         else if(zsize<3)
  199.             copybw(base,xsize*ysize);
  200.         fclose(inf);
  201.         free(verdat);
  202.         free(image);
  203.         return base;
  204.     }
  205. }
  206.  
  207.  
  208.  
  209. /* static utility functions for longimagedata */
  210.  
  211. static interleaverow(lptr,cptr,z,n)
  212. unsigned char *lptr, *cptr;
  213. int z, n;
  214. {
  215.     lptr += z;
  216.     while(n--) {
  217.         *lptr = *cptr++;
  218.         lptr += 4;
  219.     }
  220. }
  221.  
  222. static copybw(lptr,n)
  223. long *lptr;
  224. int n;
  225. {
  226.     while(n>=8) {
  227.         lptr[0] = 0xff000000+(0x010101*(lptr[0]&0xff));
  228.         lptr[1] = 0xff000000+(0x010101*(lptr[1]&0xff));
  229.         lptr[2] = 0xff000000+(0x010101*(lptr[2]&0xff));
  230.         lptr[3] = 0xff000000+(0x010101*(lptr[3]&0xff));
  231.         lptr[4] = 0xff000000+(0x010101*(lptr[4]&0xff));
  232.         lptr[5] = 0xff000000+(0x010101*(lptr[5]&0xff));
  233.         lptr[6] = 0xff000000+(0x010101*(lptr[6]&0xff));
  234.         lptr[7] = 0xff000000+(0x010101*(lptr[7]&0xff));
  235.         lptr += 8;
  236.         n-=8;
  237.     }
  238.     while(n--) {
  239.         *lptr = 0xff000000+(0x010101*(*lptr&0xff));
  240.         lptr++;
  241.     }
  242. }
  243. static setalpha(lptr,n)
  244. unsigned char *lptr;
  245. {
  246.     while(n>=8) {
  247.         lptr[0*4] = 0xff;
  248.         lptr[1*4] = 0xff;
  249.         lptr[2*4] = 0xff;
  250.         lptr[3*4] = 0xff;
  251.         lptr[4*4] = 0xff;
  252.         lptr[5*4] = 0xff;
  253.         lptr[6*4] = 0xff;
  254.         lptr[7*4] = 0xff;
  255.         lptr += 4*8;
  256.         n -= 8;
  257.     }
  258.     while(n--) {
  259.         *lptr = 0xff;
  260.         lptr += 4;
  261.     }
  262. }
  263. static expandrow(optr,iptr,z)
  264. unsigned char *optr, *iptr;
  265. int z;
  266. {
  267.     unsigned char pixel, count;
  268.  
  269.     optr += z;
  270.     while(1) {
  271.         pixel = *iptr++;
  272.         if ( !(count = (pixel & 0x7f)) )
  273.             return;
  274.         if(pixel & 0x80) {
  275.             while(count>=8) {
  276.                 optr[0*4] = iptr[0];
  277.                 optr[1*4] = iptr[1];
  278.                 optr[2*4] = iptr[2];
  279.                 optr[3*4] = iptr[3];
  280.                 optr[4*4] = iptr[4];
  281.                 optr[5*4] = iptr[5];
  282.                 optr[6*4] = iptr[6];
  283.                 optr[7*4] = iptr[7];
  284.                 optr += 8*4;
  285.                 iptr += 8;
  286.                 count -= 8;
  287.             }
  288.             while(count--) {
  289.                 *optr = *iptr++;
  290.                 optr+=4;
  291.             }
  292.         } else {
  293.             pixel = *iptr++;
  294.             while(count>=8) {
  295.                 optr[0*4] = pixel;
  296.                 optr[1*4] = pixel;
  297.                 optr[2*4] = pixel;
  298.                 optr[3*4] = pixel;
  299.                 optr[4*4] = pixel;
  300.                 optr[5*4] = pixel;
  301.                 optr[6*4] = pixel;
  302.                 optr[7*4] = pixel;
  303.                 optr += 8*4;
  304.                 count -= 8;
  305.             }
  306.             while(count--) {
  307.                 *optr = pixel;
  308.                 optr+=4;
  309.             }
  310.         }
  311.     }
  312. }
  313.  
  314. /*
  315.  *      addlongimgtag -
  316.  *              this is used to extract image data from core dumps.
  317.  *
  318.  */
  319. addlongimgtag(dptr,xsize,ysize)
  320. unsigned long *dptr;
  321. int xsize, ysize;
  322. {
  323.     dptr = dptr+(xsize*ysize);
  324.     dptr[0] = 0x12345678;
  325.     dptr[1] = 0x59493333;
  326.     dptr[2] = 0x69434222;
  327.     dptr[3] = xsize;
  328.     dptr[4] = ysize;
  329. }
  330.